﻿namespace DomainServices.Tools.SharedTypes
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.ServiceModel.DomainServices;

    internal class SharedSourceFiles
    {
        private bool _anySharedFiles;
        private FilenameMap _filenameMap;
        private HashSet<int> _sharedFileIds = new HashSet<int>();
        private ISourceFileLocationService _sourceFileLocationService;
        internal const int NotShared = 0;

        internal SharedSourceFiles(ISourceFileLocationService sourceFileLocationService, FilenameMap filenameMap, IEnumerable<string> sharedFiles)
        {
            this._sourceFileLocationService = sourceFileLocationService;
            this._filenameMap = filenameMap;
            this._anySharedFiles = sharedFiles.Any<string>();
            if (this._anySharedFiles)
            {
                foreach (string str in sharedFiles)
                {
                    this._sharedFileIds.Add(this._filenameMap.AddOrGet(str));
                }
            }
        }

        private int FileNameToSharedID(string file)
        {
            if (string.IsNullOrEmpty(file))
            {
                return 0;
            }
            int item = this._filenameMap.AddOrGet(file);
            if (!this._sharedFileIds.Contains(item))
            {
                return 0;
            }
            return item;
        }

        internal int[] GetSharedFileIds(CodeMemberKey key)
        {
            System.Func<string, int> func = null;
            if (!this._anySharedFiles)
            {
                return null;
            }
            Type type = key.Type;
            if ((type == null) || type.Assembly.IsSystemAssembly())
            {
                return null;
            }
            int[] numArray = null;
            switch (key.KeyKind)
            {
                case CodeMemberKey.CodeMemberKeyKind.TypeKey:
                {
                    IEnumerable<string> filesForType = this.SourceFileLocationService.GetFilesForType(type);
                    if ((filesForType == null) || !filesForType.Any<string>())
                    {
                        return numArray;
                    }
                    if (func == null)
                    {
                        func = s => this.FileNameToSharedID(s);
                    }
                    int[] numArray2 = (from i in Enumerable.Select<string, int>(filesForType, func).Distinct<int>()
                        where i != 0
                        select i).ToArray<int>();
                    return ((numArray2.Length == 0) ? null : numArray2);
                }
                case CodeMemberKey.CodeMemberKeyKind.PropertyKey:
                {
                    PropertyInfo propertyInfo = key.PropertyInfo;
                    if (propertyInfo != null)
                    {
                        string fileForMember = this.SourceFileLocationService.GetFileForMember(propertyInfo);
                        int num = this.FileNameToSharedID(fileForMember);
                        if (num != 0)
                        {
                            numArray = new int[] { num };
                        }
                        return numArray;
                    }
                    return null;
                }
                case CodeMemberKey.CodeMemberKeyKind.MethodKey:
                {
                    MethodBase methodBase = key.MethodBase;
                    if (methodBase != null)
                    {
                        string file = this.SourceFileLocationService.GetFileForMember(methodBase);
                        int num2 = this.FileNameToSharedID(file);
                        if (num2 != 0)
                        {
                            numArray = new int[] { num2 };
                        }
                        return numArray;
                    }
                    return null;
                }
            }
            return numArray;
        }

        private ISourceFileLocationService SourceFileLocationService
        {
            get
            {
                return this._sourceFileLocationService;
            }
        }
    }
}

